import React from 'react';
import moment from "moment/moment";
import { connect } from 'react-redux';
import { messages, deepFullCopy } from "share/common";
import { Form, Alert, Button, Icon, DatePicker, message, Select, Row , Col, Spin, Popover, Popconfirm } from 'antd';
import SubsidyItem from 'containers/expense-report/template/subsidy-item';
import subsidyService from "containers/expense-report/template/subsidy-service";
import SubsidyEditItem from 'containers/expense-report/template/subsidy-edit-item';
const FormItem = Form.Item;
const Option = Select.Option;
const {RangePicker} = DatePicker;
import Condition from 'components/condition'
const { If, Else } = Condition;
import 'styles/expense-report/template/subsidy-middle.scss';

class SubsidyMiddle extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      dataList: [],
      beforeEditDataList: [], //编辑前的dataList
      dataListId: 0,
      subsidyEndDate: undefined,
      subsidyStartDate: undefined,
      expenseReportOID: null,
      isEdit: false,
      isWithTime: false,
      userDTOList: [],
      subsidyExtendID: null,
      newOtherSubsidy: false,
      subsidySelection: false,
      withCity: true,
      subsidyLength: 0,
      submitLoading: false
    }
  }

  componentDidMount() {
    const { subsidyObj, subsidyInfo, expenseReportOID, isWithTime, newOtherSubsidy, subsidyLength } = this.props;
    let tempData = JSON.parse(JSON.stringify(subsidyObj.expenseReportSubsidyDTOS));
    tempData.map((item, index) => {
      item.idealID = index + 1;
      tempData[index] = item;
    });
    this.setState({
      dataList: tempData,
      dataListId: tempData.length + 1,
      subsidyEndDate: subsidyInfo.showExtend ? subsidyObj.subsidyEndDate : subsidyInfo.reportEndDate,
      subsidyStartDate: subsidyInfo.showExtend ? subsidyObj.subsidyStartDate : subsidyInfo.reportStartDate,
      expenseReportOID: expenseReportOID,
      isWithTime: isWithTime,
      userDTOList: subsidyObj.userDTOList,
      subsidyExtendID: subsidyObj.subsidyExtendID,
      newOtherSubsidy: newOtherSubsidy,
      subsidySelection: subsidyInfo.subsidySelection,
      withCity: subsidyInfo.withCity,
      isEdit: false,
      subsidyLength: subsidyLength
    }, () => {
      // 若当前大行程下没有小行程，则需要显示一个编辑中的小行程
      tempData.length === 0 && this.addSubsidy()
    });
  }

  componentWillReceiveProps(nextProps) {
    const { subsidyObj, subsidyLength, expenseReportOID, isWithTime, newOtherSubsidy, subsidyInfo } = nextProps;
    if(subsidyObj){
      if(JSON.stringify(subsidyObj) === JSON.stringify(this.props.subsidyObj)){
        let copyData = JSON.parse(JSON.stringify(subsidyObj.expenseReportSubsidyDTOS));
        copyData.map((item, index) => {
          item.idealID = index + 1;
          copyData[index] = item;
        });
        this.setState({
          subsidyLength: subsidyLength,
          dataList: copyData,
          dataListId: copyData.length + 1
        });
        return -1;
      }
      let tempData = JSON.parse(JSON.stringify(subsidyObj.expenseReportSubsidyDTOS));
      tempData.map((item, index) => {
        item.idealID = index + 1;
        tempData[index] = item;
      });
      this.setState({
        dataList: tempData,
        dataListId: tempData.length + 1,
        subsidyEndDate: subsidyInfo.showExtend ? subsidyObj.subsidyEndDate : subsidyInfo.reportEndDate,
        subsidyStartDate: subsidyInfo.showExtend ? subsidyObj.subsidyStartDate : subsidyInfo.reportStartDate,
        expenseReportOID: expenseReportOID,
        isWithTime: isWithTime,
        isEdit: false,
        userDTOList: subsidyObj.userDTOList,
        subsidyExtendID: subsidyObj.subsidyExtendID,
        newOtherSubsidy: newOtherSubsidy,
        subsidySelection: subsidyInfo.subsidySelection,
        withCity: subsidyInfo.withCity,
        subsidyLength: subsidyLength
      }, () => {
        // 若当前大行程下没有小行程，则需要显示一个编辑中的小行程
        tempData.length === 0 && this.addSubsidy()
      });
    }
  }

  // 渲染费用归属人
  renderUser = () => {
    const { isEdit, userDTOList, newOtherSubsidy } = this.state;
    const {userOption} = this.props;
    let str = '';
    userDTOList.map((item,index) => {
      index === userDTOList.length - 1 ? (str += item.fullName) : (str += `${item.fullName},`);
    });
    return isEdit && newOtherSubsidy ? (
      <Select allowClear
              placeholder={messages('common.select')}
              mode='multiple'
              getPopupContainer={triggerNode => triggerNode.parentNode}>
        {
          userOption.map(item => {
            return <Option key={item.id} title={item.fullName}>{item.fullName}</Option>
          })
        }
      </Select>
    ) : (
      <div style={{whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden'}}>
        <Popover content={str} placement='topLeft'>{str}</Popover>
      </div>
    )
  };

  disabledDate = (value) => {
    const { subsidyInfo } = this.props;
    if (subsidyInfo.reportStartDate && subsidyInfo.reportEndDate) {
      let startDate = moment(moment(subsidyInfo.reportStartDate).local().format('YYYY-MM-DD HH:mm:ss'));
      let endDate = moment(moment(subsidyInfo.reportEndDate).local().format('YYYY-MM-DD HH:mm:ss'));
      return value && (value.valueOf() < startDate.valueOf() || value.valueOf() > endDate.valueOf());
    }
    return false
  };

  renderGoBackDate = () => {
    const {isEdit, subsidyStartDate, subsidyEndDate, isWithTime} = this.state;
    let formatDate = isWithTime ? 'YYYY-MM-DD HH:mm' : 'YYYY-MM-DD';
    return isEdit ? (
      <RangePicker
        format={formatDate}
        showTime={isWithTime ? {defaultValue: [moment('00:00', 'HH:mm'), moment('23:59', 'HH:mm')], format: 'HH:mm'} : false}
        style={{width: 'auto'}}
        disabledDate={this.disabledDate}
      />
    ) : (
      <div>
        {moment(subsidyStartDate).format(formatDate)} ~ {moment(subsidyEndDate).format(formatDate)}
      </div>
    )
  };

  // 检查大行程信息是否已更改（费用归属人、出差往返日期）
  checkSubsidyChange = (values) => {
    const { subsidyObj } = this.props;
    if (
      new Date(subsidyObj.subsidyStartDate).getTime() !== new Date(values['goBackDate'][0]).getTime() ||
      new Date(subsidyObj.subsidyEndDate).getTime() !== new Date(values['goBackDate'][1]).getTime() ||
      subsidyObj.userDTOList.length !== values['userIDs'].length
    ) {
      return true;
    }
    let userNotChange = true;
    subsidyObj.userDTOList.map(item => {
      userNotChange = values['userIDs'].some(id => id === item.id)
    });
    return !userNotChange;
  };

  // 更改大行程的费用归属人或出差往返日期
  handleSaveGoBackDate = () => {
    const { subsidyObj, userOption } = this.props;
    const { isEdit, expenseReportOID, subsidyExtendID, userDTOList, newOtherSubsidy } = this.state;
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (!err) {
        // 大行程没有任何改变时，点击【更改】相当于点【取消】
        if (!this.checkSubsidyChange(values)) {
          this.editGoBackDate();
          return
        }
        this.setState({ isEdit: !isEdit }, () => {
          this.props.validateSave(this.props.index, this.state.isEdit);
        });
        let selectedUserList = [];
        newOtherSubsidy && values['userIDs'] && values['userIDs'].map(id => {
          selectedUserList.push(userOption.filter(item => item.id === id)[0])
        });
        let params = {
          expenseReportSubsidyDTOS: subsidyObj.expenseReportSubsidyDTOS,
          subsidyStartDate: moment(values['goBackDate'][0]).utc(),
          subsidyEndDate: moment(values['goBackDate'][1]).utc(),
          userDTOList: newOtherSubsidy ? selectedUserList : userDTOList,
          subsidyExtendID,
          expenseReportOID
        };
        this.setState({ submitLoading: true });
        subsidyService.changeDate(params).then(res => {
          this.setState({
            submitLoading: false,
            dataList: res.data.expenseReportSubsidyDTOS,
            subsidyStartDate: res.data.subsidyStartDate,
            subsidyEndDate: res.data.subsidyEndDate,
            subsidyExtendID: res.data.subsidyExtendID,
            userDTOList: res.data.userDTOList
          },() => {
            let { dataList } = this.state;
            dataList.map(item => item.edit = true);
            let params = {
              index: this.props.index,
              dataList: this.state.dataList,
              hasEdit: true,
              allObj: res.data
            };
            this.props.handleChange(params);
            this.props.changeHeader();
          });
        }).catch(() => {
          this.setState({submitLoading: false});
          message.error(messages('expense-parent-report.key66'/*出错了*/));
        })
      } else {
        message.error(messages('expense-parent-report.key160')/*必填信息请填写完整*/);
      }
    });
  };

  editGoBackDate = () => {
    const {isEdit} = this.state;
    this.setState({isEdit: !isEdit},() => {
      this.props.validateSave(this.props.index,this.state.isEdit);
    });
  };

  handleChange = (data, value, type) => {
    const { dataList } = this.state;
    dataList.map((item, index) => {
      if (item.idealID === data.idealID) {
        value.map((val, index) => {
          let res = val;
          if (type[index] === 'startDate' || type[index] === 'endDate') {
            res = val ? moment(val).utc() : null;
          }
          item[type[index]] = res;
        });
        dataList[index] = item;
      }
    });
    let params = {
      index: this.props.index,
      dataList: dataList,
      hasEdit: true
    };
    this.props.handleChange(params);
    this.setState({ dataList });
  };

  // 小行程编辑／取消编辑
  handleEdit = (values, isEdit = true) => {
    let { dataList, beforeEditDataList } = this.state;
    let allTrue = isEdit ? this.verification() : true;
    if (allTrue) {
      dataList.map((item, index) => {
        if (item.idealID === values.idealID) {
          // 取消编辑时恢复到编辑前的状态
          !isEdit && (dataList[index] = beforeEditDataList[index]);
          dataList[index].edit = isEdit;
          dataList[index].showCancelEdit = isEdit;
        } else {
          dataList[index].edit = false;
        }
      });
      let params = { index: this.props.index, dataList };
      !isEdit && this.props.handleChange(params);
      this.setState({ dataList, beforeEditDataList: deepFullCopy(dataList) });
    }
  };

  handleDelete = (data) => {
    let {dataList} = this.state;
    dataList.map((item,index) => {
      if(item.idealID === data.idealID){
        dataList[index] = undefined;
      }
    });
    dataList = dataList.filter(item => !!item);
    let params = {
      index: this.props.index,
      dataList: dataList,
      hasEdit: true
    };
    this.props.handleChange(params);
    this.setState({dataList});
  };

  // 添加小行程
  addSubsidy = () => {
    const { subsidyObj } = this.props;
    let { dataListId, dataList, subsidyStartDate, subsidyEndDate, subsidyExtendID } = this.state;
    let startDate = '';
    let allTrue = this.verification();
    if (allTrue) {
      dataList.length === 0 && (startDate = subsidyObj.subsidyStartDate);
      dataList.map((item, index) => {
        item.edit = false;
        if (subsidyEndDate) {
          startDate = (
            index === dataList.length - 1 ?
              ((moment(subsidyEndDate).isBefore(moment(item.endDate).subtract(-1, 'days')) ?
                subsidyEndDate : moment(item.endDate).subtract(-1, 'days'))) :
              subsidyStartDate
          );
        } else {
          startDate = (
            index === dataList.length - 1 ?
              moment(item.endDate).subtract(-1, 'days') :
              subsidyObj.subsidyStartDate
          );
        }
        dataList[index] = item;
      });
      dataList.push({
        edit: true,
        idealID: dataListId,
        startDate,
        endDate: subsidyEndDate || startDate,
        international: false,
        dpCityInternational: false,
        subsidyExtendID: subsidyExtendID
      });
      dataListId += 1;
      this.setState({ dataList, dataListId });
      let params = {
        index: this.props.index,
        dataList: dataList,
        hasEdit: true
      };
      this.props.handleChange(params);
    }
  };

  verification = () => {
    let { dataList, withCity } = this.state;
    let result = true;
    let errorMessage = [];
    let errorMessageType = []; //为了过滤掉相同的报错
    dataList.map(item => {
      item.error = false;
      if (item.edit) {
        item.error = true;
        result = false;
        // 该城市无差补类型 未选择差补类型 统一报错必填信息未填
        if (!((typeof item.international === 'boolean') &&
            ((withCity && item.cityName) || !withCity) &&
            item.startDate && item.endDate &&
            item.expenseTypes && item.expenseTypeOIDs
          ) || item.expenseTypes.length === 0 ||
          item.expenseTypeOIDs.length === 0) {
          if (!~errorMessageType.indexOf(1)) {
            errorMessage.push(messages('expense-parent-report.key67'/*必填信息未填*/));
            errorMessageType.push(1);
          }
        } else if (item.remark && item.remark.length > 200) {
          if (!~errorMessageType.indexOf(2)) {
            errorMessage.push(messages('common.max.characters.length', {max: 200}));
            errorMessageType.push(2);
          }
        } else {
          item.error = false;
          result = true;
        }
      }
    });
    if (errorMessage.length) {
      errorMessage.length === 1 ? message.error(errorMessage[0]) :
        message.error(
          errorMessage.map((item, index) => <p style={{textAlign: 'left', marginLeft: 5}}>{index + 1}: {item} </p>)
        )
    }
    this.setState({ dataList });
    return result;
  };

  renderAlertContent = () => (
    <div>
      {messages('expense-parent-report.key242')/*更改费用归属人或者出差往返日期，可能更改相应行程日期，请重新选择生成的补贴。*/}
      <div>
        <a onClick={this.handleSaveGoBackDate}>{messages('expense-parent-report.key73'/*更改*/)}</a>
        <span className="ant-divider"/>
        <a onClick={this.editGoBackDate}>{messages('common.cancel')/*取消*/}</a>
      </div>
    </div>
  );

  render(){
    const { formOID, subsidyInfo } = this.props;
    const { dataList, subsidyEndDate, subsidyStartDate, expenseReportOID, isWithTime, isEdit, subsidyExtendID,
      userDTOList, withCity, subsidySelection, subsidyLength, submitLoading } = this.state;
    const { getFieldDecorator } = this.props.form;
    const formItemLayout = {
      labelCol: { span: 10 },
      wrapperCol: { span: 14 }
    };
    let formatDate = isWithTime ? 'YYYY-MM-DD HH:mm' : 'YYYY-MM-DD';
    let ids = [];
    userDTOList && userDTOList.map(item => ids.push(String(item.id)));
    return(
      <div className={subsidyInfo.showExtend ? 'subsidy-middle' : ''}>
        <Spin spinning={submitLoading}>
          <If value={subsidyInfo.showExtend}>
            <div className='subsidy-header-info'>
              <Form>
                <Row>
                  <Col span={isEdit ? 9 : 8}>
                    <FormItem label={messages('expense-parent-report.key105')/*费用归属人*/} {...formItemLayout}>
                      {getFieldDecorator('userIDs', {
                        rules: [{
                          required: isEdit,
                          message: ' '
                        }],
                        initialValue: ids
                      })(
                        this.renderUser()
                      )}
                    </FormItem>
                  </Col>
                  <Col span={isEdit ? 14 : 12}>
                    <FormItem
                      label={messages('expense-parent-report.key70'/*出差往返日期*/)}
                      labelCol={{span: 6}}
                      wrapperCol={{span: 18}}
                    >
                      {getFieldDecorator('goBackDate', {
                        rules: [{
                          required: isEdit,
                          message: ' '
                        }],
                        initialValue: (subsidyStartDate && subsidyEndDate) ?
                          [moment(moment(subsidyStartDate), formatDate), moment(moment(subsidyEndDate), formatDate)] : undefined
                      })(
                        this.renderGoBackDate()
                      )}
                    </FormItem>
                  </Col>
                  <div className="big-subsidy-operate">
                    <If value={!isEdit}>
                      <a onClick={this.editGoBackDate}>{messages('common.edit')/*编辑*/}</a>
                      <If value={subsidyLength > 1}>
                        <span className="ant-divider"/>
                        <Popconfirm
                          placement="bottomRight"
                          title={messages('common.confirm.delete')/*确定要删除吗？*/}
                          getPopupContainer={() => document.getElementsByClassName('big-subsidy-operate')[0]}
                          onConfirm={() => this.props.deleteSubsidy(this.props.index)}
                        >
                          <a className="button-delete">{messages('common.delete')/*删除*/}</a>
                        </Popconfirm>
                      </If>
                    </If>
                  </div>
                </Row>
              </Form>
              <If value={isEdit}>
                <Alert
                  message={messages('expense-parent-report.key71'/*请注意*/)}
                  description={this.renderAlertContent()}
                  type="warning"
                  style={{margin: 10}}
                  showIcon
                />
              </If>
            </div>
          </If>
          {dataList.map((item, index) => (
            <div key={index} className={`subsidy-item-container ${item.error ? 'error-item' : ''}`}>
              <Condition>
                <If value={item.edit}>
                  <SubsidyEditItem
                    key={index}
                    subsidyIndex={index + 1}
                    applyData={item}
                    subsidyStartDate={subsidyStartDate}
                    subsidyEndDate={subsidyEndDate}
                    subsidyExtendID={subsidyExtendID}
                    withCity={withCity}
                    subsidySelection={subsidySelection}
                    expenseReportOID={expenseReportOID}
                    isAutoCalculateEnabled={subsidyInfo.isAutoCalculateEnabled}
                    formOID={formOID}
                    dataList={dataList}
                    userDTOList={userDTOList}
                    showExtend={subsidyInfo.showExtend}
                    onObjectChange={this.handleChange}
                    onDelete={this.handleDelete}
                    onCancelEdit={item => this.handleEdit(item, false)}
                  />
                </If>
                <Else>
                  <SubsidyItem
                    key={index}
                    subsidyIndex={index + 1}
                    applyData={item}
                    withCity={withCity}
                    dataList={dataList}
                    isAutoCalculateEnabled={subsidyInfo.isAutoCalculateEnabled}
                    onEdit={this.handleEdit}
                    onDelete={this.handleDelete}
                  />
                </Else>
              </Condition>
            </div>
          ))}
          <Button type="dashed" onClick={this.addSubsidy} className="button-add-subsidy">
            <Icon type="plus"/> {messages('common.add')/*添加*/}
          </Button>
        </Spin>
      </div>
    )
  }
}

SubsidyMiddle.propTypes = {
  subsidyObj: React.PropTypes.object,
  expenseReportOID: React.PropTypes.string.isRequired,
  isWithTime: React.PropTypes.bool,
  handleChange: React.PropTypes.func,
  index: React.PropTypes.number,
  userOption: React.PropTypes.array,
  changeHeader: React.PropTypes.func,
  newOtherSubsidy: React.PropTypes.bool,
  deleteSubsidy: React.PropTypes.func,
  subsidyLength: React.PropTypes.number,
  validateSave: React.PropTypes.func,
  formOID: React.PropTypes.string,
  subsidyInfo: React.PropTypes.object,
};

SubsidyMiddle.defaultProps = {
  subsidyObj: {},
  isWithTime: false,
  handleChange: () => {},
  userOption: [],
  changeHeader: () => {},
  newOtherSubsidy: false,
  subsidyLength: 0,
  subsidyInfo: {}
};

const wrappedSubsidyMiddle = Form.create()(SubsidyMiddle);
export default connect()(wrappedSubsidyMiddle);
